Proper fix for profile_pc on x86_64.
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Wed, 1 Feb 2006 15:01:04 +0000 (15:01 +0000)
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Wed, 1 Feb 2006 15:01:04 +0000 (15:01 +0000)
Also enable CONFIG_FRAME_POINTER for dom0 and domU kernels.

Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
buildconfigs/linux-defconfig_xen0_x86_32
buildconfigs/linux-defconfig_xen0_x86_64
buildconfigs/linux-defconfig_xenU_x86_32
buildconfigs/linux-defconfig_xenU_x86_64
linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c

index 245f74f960a7e7280faea1f136a8086118bcc9e7..a8efa792b87260919c4a3e91382122176e94c2b2 100644 (file)
@@ -1228,7 +1228,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_EARLY_PRINTK=y
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_KPROBES is not set
index c6a4c24ede9d302100de3ea1aea15519aee274bb..e140ede4ade077e4d26c5b6c173f3360033a92ed 100644 (file)
@@ -1173,7 +1173,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_FS is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 # CONFIG_CHECKING is not set
 # CONFIG_INIT_DEBUG is not set
 # CONFIG_KPROBES is not set
index 2180a714fc53f109e41484e62791f035fea59f04..ca3b4eb52c42410f671c73ce8d0ed4f422f7d443 100644 (file)
@@ -518,7 +518,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_EARLY_PRINTK=y
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_KPROBES is not set
index 5f5b171cae400216ec9c799cfaac6f73a5553348..32244b357cffb8f1f7683c4cf5a36804ebfe2ef4 100644 (file)
@@ -895,7 +895,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_FS is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 # CONFIG_INIT_DEBUG is not set
 # CONFIG_KPROBES is not set
 
index 32a53bfaae91ba1d9bbad9c8cb3a46d491071719..b3a0a64b804d88b3c2e403596cd502154f96d907 100644 (file)
@@ -58,6 +58,7 @@
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 #include <asm/timer.h>
+#include <asm/sections.h>
 
 #include "mach_time.h"
 
@@ -541,22 +542,33 @@ unsigned long long sched_clock(void)
 }
 
 #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
-#ifdef __x86_64__
-#define REG_BP rbp
-#else
-#define REG_BP ebp
-#endif
 unsigned long profile_pc(struct pt_regs *regs)
 {
        unsigned long pc = instruction_pointer(regs);
 
+#ifdef __x86_64__
+       /* Assume the lock function has either no stack frame or only a single word.
+          This checks if the address on the stack looks like a kernel text address.
+          There is a small window for false hits, but in that case the tick
+          is just accounted to the spinlock function.
+          Better would be to write these functions in assembler again
+          and check exactly. */
+       if (in_lock_functions(pc)) {
+               char *v = *(char **)regs->rsp;
+               if ((v >= _stext && v <= _etext) ||
+                       (v >= _sinittext && v <= _einittext) ||
+                       (v >= (char *)MODULES_VADDR  && v <= (char *)MODULES_END))
+                       return (unsigned long)v;
+               return ((unsigned long *)regs->rsp)[1];
+       }
+#else
        if (in_lock_functions(pc))
                return *(unsigned long *)(regs->REG_BP + 4);
+#endif
 
        return pc;
 }
 EXPORT_SYMBOL(profile_pc);
-#undef REG_BP
 #endif
 
 irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)